package com.itts.threadUtils;

import org.junit.Test;

import java.util.concurrent.*;

public class ThreadDemo1 extends Thread{
    /**
     * 线程池的七大参数
     */
    @Test
    public void test() {
        CountDownLatch count = new CountDownLatch(5);
        //todo 禁止使用Executors 创建线程(阿里手册规范)
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5, // 线程池中的常驻核心线程数 _初始值
                7,  //线程池能够容纳同时执行的最大线程数, 此值大于等于1 可以用cpu核数(Runtime.getRuntime().availableProcessors())
                100L, // 多余的空闲线程存活时间, 当空间时间达到keepAliveTime值时,多余的线程会被销毁直到只剩下corePoolSize个线程为止
                TimeUnit.SECONDS,  //keepAliveTime的单位
                new LinkedBlockingQueue<>(5),//workQueue: 等候区  任务队列 被提交但未被执行的任务
                Executors.defaultThreadFactory(), // 创建线程的工厂
                new ThreadPoolExecutor.AbortPolicy()); //handler : 拒绝策略 , 表示当线程队列满了并且工作线程大于等于线程池的最大显示数(MaxnumpoolSize)时 如何拒绝
        try {
            for (int i = 1; i <= 20; i++) {
                final int finalI = i;
                executor.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"号窗口,"+ "服务顾客"+ finalI);
                    count.countDown();
                });
            }
            count.await();
            System.out.println("第组");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            executor.shutdown();//关闭线程
        }
    }
    /**
     * 线程的四大拒绝策略
     *
     * 第一种拒绝策略
     * new ThreadPoolExecutor.AbortPolicy() ,如果线程满了，则不处理新的进程，抛出异常；
     *
     * 第二种处理策略
     * new ThreadPoolExecutor.CallerRunsPolicy() 线程池满了，如果有新的哪里来的去哪里，不会抛出异常； 如果超额，这里会交给main线程
     *
     * 第三种处理策略：
     * new ThreadPoolExecutor.DiscardPolicy()，线程池满了，丢掉线程，不会抛出异常  如果超额，这里会交给main线程
     *
     * 第四种处理策略：
     * new ThreadPoolExecutor.DiscardOldestPolicy()， 线程池满了，会尝试和最早的线程去竞争，如果成功则加入，否则丢弃，不会抛出异常  如果超额，这里会交给main线程
     */

    @Test
    public void test2(){
        CountDownLatch count = new CountDownLatch(5);
        for (int i = 1; i <= 5; i++) {
            int finalI = i;
            new Thread(()->{
                System.out.println("线程"+Thread.currentThread().getName()+"执行");
                count.countDown();  //计数器减一
            },
                    String.valueOf(i)).start();
        }
        try {
            count.await();
            System.out.println("执行完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
